﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.CApAPPObjectFlowTask
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using EngineeringInternalExtension;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Tecnomatix.Engineering;


namespace DnProcessSimulateCommands;

public class CApAPPObjectFlowTask : CApAPPTask
{
  private TxTransformation m_initialGripLocation;

  public CApAPPObjectFlowTask(ITxOperation i_objectFlowOperation)
    : base(i_objectFlowOperation)
  {
    this.fillTask(i_objectFlowOperation);
  }

  public override TxObjectList GetAllLocations()
  {
    TxObjectList allLocations = new TxObjectList();
    for (int index = 0; index < ((ITxObjectCollection) (this.Operation as ITxOrderedObjectCollection)).Count; ++index)
    {
      ITxObject childAt = (this.Operation as ITxOrderedObjectCollection).GetChildAt(index);
      ((Collection<ITxObject>) allLocations).Add(childAt);
    }
    return allLocations;
  }

  public TxObjectFlowOperation ObjectFlowOperation => this.Operation as TxObjectFlowOperation;

  public virtual void fillTask(ITxOperation i_objectFlowOperation)
  {
    if (i_objectFlowOperation == null)
      return;
    TxObjectList operationLocations = CApAPPUtilities.GetOperationLocations(i_objectFlowOperation);
    int num = 0;
    List<KiAppObjectFlowWaypointEx> objectFlowWaypointExList = new List<KiAppObjectFlowWaypointEx>();
    foreach (ITxObject i_location in (Collection<ITxObject>) operationLocations)
    {
      if (i_location is ITxLocationOperation)
      {
        bool flag1 = false;
        bool flag2 = false;
        string name = i_location.Name;
        KiAppLocationEx locationFromTxLoc = CApAPPObjectFlowTask.CreateAppLocationFromTxLoc(i_location as ITxLocationOperation);
        if (num == 0)
        {
          flag2 = true;
          flag1 = true;
        }
        else if (num == ((Collection<ITxObject>) operationLocations).Count - 1)
        {
          flag2 = true;
          flag1 = true;
        }
        switch (i_location)
        {
          case TxWeldLocationOperation _:
          case TxRoboticSeamOperation _:
            flag1 = true;
            flag2 = true;
            break;
        }
        KiAppWaypointStatus appWaypointStatus = (KiAppWaypointStatus) 0;
        KiAppObjectFlowWaypointEx objectFlowWaypointEx = new KiAppObjectFlowWaypointEx(locationFromTxLoc, name, flag2, appWaypointStatus);
        ((KiAppWaypointEx) objectFlowWaypointEx).Locked = flag1;
        objectFlowWaypointExList.Add(objectFlowWaypointEx);
        ++num;
      }
    }
    this.KiTask = (KiAppTaskEx) new KiAppObjectFlowTaskEx(i_objectFlowOperation as TxObjectFlowOperation, (IList<KiAppObjectFlowWaypointEx>) objectFlowWaypointExList);
    this.SynchronizedWaypointList = this.Waypoints();
  }

  public TxTransformation MagnetPointPosition
  {
    set => this.KiObjectFlowTask.MagnetPointPosition = value;
    get => this.KiObjectFlowTask.MagnetPointPosition;
  }

  public TxTransformation RelativeGripPosition => this.KiObjectFlowTask.RelativeGripPosition;

  private static KiAppLocationEx CreateAppLocationFromTxLoc(ITxLocationOperation i_location)
  {
    KiAppLocationEx locationFromTxLoc = new KiAppLocationEx();
    if (i_location is ITxLocatableObject itxLocatableObject)
      locationFromTxLoc.AbsoluteLocation = itxLocatableObject.AbsoluteLocation;
    return locationFromTxLoc;
  }

  public override void AddLocationFromWaypoint(
    CApAPPWaypoint i_waypoint,
    ITxObject i_previousLocation)
  {
    TxObjectFlowLocationOperation locationOperation = this.ObjectFlowOperation.CreateObjectFlowLocationOperation(new TxObjectFlowLocationOperationCreationData());
    if (!TxObjectFlowLocationOperation.op_Inequality(locationOperation, (ITxObject) null))
      return;
    locationOperation.Name = i_waypoint.Name;
    locationOperation.AbsoluteLocation = i_waypoint.StoredApproachLocation.AbsoluteLocation;
    if (i_previousLocation == null)
      return;
    this.ObjectFlowOperation.MoveChildAfter((ITxObject) locationOperation, i_previousLocation);
  }

  public void ComputeMinTranslationLimitsValues(
    out double txMinValue,
    out double txMaxValue,
    out double tyMinValue,
    out double tyMaxValue,
    out double tzMinValue,
    out double tzMaxValue)
  {
    this.KiObjectFlowTask.ComputeMinTranslationLimitsValues(ref txMinValue, ref txMaxValue, ref tyMinValue, ref tyMaxValue, ref tzMinValue, ref tzMaxValue);
  }

  public bool AreTranslationLimitsValid(
    AxisType axisType,
    CApAPPObjectFlowTask.LimitsCheckMode checkMode,
    CApAPPWaypoint startPoint,
    List<CApAPPWaypoint> fixedWaypoints,
    out List<CApAPPWaypoint> wpTranslationLimitsError)
  {
    bool flag1 = true;
    bool flag2 = false;
    double num1 = 0.0;
    double num2 = 0.0;
    wpTranslationLimitsError = new List<CApAPPWaypoint>();
    KiAppLimitDofStatus appLimitDofStatus = (KiAppLimitDofStatus) 0;
    KiAppLimitsEx limits = this.KiObjectFlowTask.GetLimits();
    switch (axisType)
    {
      case AxisType.AXIS_TX:
        flag2 = limits.TxDofStatus != null || checkMode == CApAPPObjectFlowTask.LimitsCheckMode.DontConsiderDofStatus;
        if (flag2)
        {
          appLimitDofStatus = limits.TxDofStatus;
          num1 = limits.TxMinValue;
          num2 = limits.TxMaxValue;
          break;
        }
        break;
      case AxisType.AXIS_TY:
        flag2 = limits.TyDofStatus != null || checkMode == CApAPPObjectFlowTask.LimitsCheckMode.DontConsiderDofStatus;
        if (flag2)
        {
          appLimitDofStatus = limits.TyDofStatus;
          num1 = limits.TyMinValue;
          num2 = limits.TyMaxValue;
          break;
        }
        break;
      case AxisType.AXIS_TZ:
        flag2 = limits.TzDofStatus != null || checkMode == CApAPPObjectFlowTask.LimitsCheckMode.DontConsiderDofStatus;
        if (flag2)
        {
          appLimitDofStatus = limits.TzDofStatus;
          num1 = limits.TzMinValue;
          num2 = limits.TzMaxValue;
          break;
        }
        break;
    }
    if (checkMode == CApAPPObjectFlowTask.LimitsCheckMode.DontConsiderDofStatus)
      appLimitDofStatus = (KiAppLimitDofStatus) 1;
    if (flag2)
    {
      TxTransformation absoluteLocation1 = startPoint.SimulatedApproachLocation.AbsoluteLocation;
      for (int index = 0; index < fixedWaypoints.Count; ++index)
      {
        TxTransformation absoluteLocation2 = fixedWaypoints[index].SimulatedApproachLocation.AbsoluteLocation;
        TxVector translation = TxTransformation.op_Multiply(absoluteLocation1.Inverse, absoluteLocation2).Translation;
        double num3 = 0.0;
        switch (axisType)
        {
          case AxisType.AXIS_TX:
            num3 = translation.X;
            break;
          case AxisType.AXIS_TY:
            num3 = translation.Y;
            break;
          case AxisType.AXIS_TZ:
            num3 = translation.Z;
            break;
        }
        if (appLimitDofStatus == 1)
        {
          if (num3 < num1)
          {
            flag1 = false;
            wpTranslationLimitsError.Add(fixedWaypoints[index]);
          }
          if (num3 > num2)
          {
            flag1 = false;
            wpTranslationLimitsError.Add(fixedWaypoints[index]);
          }
        }
        else if (Math.Abs(num3 - 0.0) > 0.0001)
        {
          flag1 = false;
          wpTranslationLimitsError.Add(fixedWaypoints[index]);
        }
      }
    }
    return flag1;
  }

  public bool AreRotationLimitsValid(
    AxisType axisType,
    CApAPPWaypoint startPoint,
    List<CApAPPWaypoint> fixedWaypoints,
    out List<CApAPPWaypoint> waypointsWithRotationLimitError)
  {
    bool flag1 = true;
    bool flag2 = false;
    double num1 = 0.0;
    double num2 = 0.0;
    waypointsWithRotationLimitError = new List<CApAPPWaypoint>();
    KiAppLimitDofStatus appLimitDofStatus = (KiAppLimitDofStatus) 0;
    switch (axisType)
    {
      case AxisType.AXIS_RX:
        flag2 = this.Limits.RxDofStatus > 0;
        if (flag2)
        {
          appLimitDofStatus = this.Limits.RxDofStatus;
          num1 = this.Limits.RxMinValue;
          num2 = this.Limits.RxMaxValue;
          break;
        }
        break;
      case AxisType.AXIS_RY:
        flag2 = this.Limits.RyDofStatus > 0;
        if (flag2)
        {
          appLimitDofStatus = this.Limits.RyDofStatus;
          num1 = this.Limits.RyMinValue;
          num2 = this.Limits.RyMaxValue;
          break;
        }
        break;
      case AxisType.AXIS_RZ:
        flag2 = this.Limits.RzDofStatus > 0;
        if (flag2)
        {
          appLimitDofStatus = this.Limits.RzDofStatus;
          num1 = this.Limits.RzMinValue;
          num2 = this.Limits.RzMaxValue;
          break;
        }
        break;
    }
    if (flag2)
    {
      TxTransformation absoluteLocation1 = startPoint.SimulatedApproachLocation.AbsoluteLocation;
      for (int index = 0; index < fixedWaypoints.Count; ++index)
      {
        TxTransformation absoluteLocation2 = fixedWaypoints[index].SimulatedApproachLocation.AbsoluteLocation;
        TxVector rotationRpyZyx = TxTransformation.op_Multiply(absoluteLocation1.Inverse, absoluteLocation2).RotationRPY_ZYX;
        double num3 = 0.0;
        switch (axisType)
        {
          case AxisType.AXIS_RX:
            num3 = rotationRpyZyx.X;
            break;
          case AxisType.AXIS_RY:
            num3 = rotationRpyZyx.Y;
            break;
          case AxisType.AXIS_RZ:
            num3 = rotationRpyZyx.Z;
            break;
        }
        if (appLimitDofStatus == 1)
        {
          if (num3 < num1)
          {
            flag1 = false;
            waypointsWithRotationLimitError.Add(fixedWaypoints[index]);
          }
          if (num3 > num2)
          {
            flag1 = false;
            waypointsWithRotationLimitError.Add(fixedWaypoints[index]);
          }
        }
        else if (Math.Abs(num3 - 0.0) > 0.0001)
        {
          flag1 = false;
          waypointsWithRotationLimitError.Add(fixedWaypoints[index]);
        }
      }
    }
    return flag1;
  }

  public bool AreRotationLimitsValid(
    AxisType axisType,
    out List<CApAPPWaypoint> waypointsWithRotationLimitError)
  {
    bool flag = true;
    waypointsWithRotationLimitError = (List<CApAPPWaypoint>) null;
    List<CApAPPWaypoint> fixedWaypointList = this.ComputeFixedWaypointList();
    if (fixedWaypointList.Count > 0)
      flag = this.AreRotationLimitsValid(axisType, this.Waypoint(0), fixedWaypointList, out waypointsWithRotationLimitError);
    return flag;
  }

  public List<CApAPPWaypoint> ComputeFixedWaypointList()
  {
    List<CApAPPWaypoint> fixedWaypointList = new List<CApAPPWaypoint>();
    int o_firstIndex = 0;
    int o_lastIndex = 0;
    this.GetActiveRange(ref o_firstIndex, ref o_lastIndex);
    if (o_firstIndex < o_lastIndex)
    {
      for (int i_index = o_firstIndex; i_index <= o_lastIndex; ++i_index)
      {
        if (this.Waypoint(i_index).Fixed)
          fixedWaypointList.Add(this.Waypoint(i_index));
      }
    }
    return fixedWaypointList;
  }

  public bool AreTranslationLimitsValid(
    CApAPPObjectFlowTask.LimitsCheckMode checkMode,
    out List<CApAPPWaypoint> listOfWaypointsWithTranslationErrors)
  {
    bool flag = true;
    listOfWaypointsWithTranslationErrors = (List<CApAPPWaypoint>) null;
    List<CApAPPWaypoint> fixedWaypointList = this.ComputeFixedWaypointList();
    if (fixedWaypointList.Count != 0)
    {
      flag = this.AreTranslationLimitsValid(AxisType.AXIS_TX, checkMode, this.Waypoint(0), fixedWaypointList, out listOfWaypointsWithTranslationErrors);
      if (flag)
        flag = this.AreTranslationLimitsValid(AxisType.AXIS_TY, checkMode, this.Waypoint(0), fixedWaypointList, out listOfWaypointsWithTranslationErrors);
      if (flag)
        flag = this.AreTranslationLimitsValid(AxisType.AXIS_TZ, checkMode, this.Waypoint(0), fixedWaypointList, out listOfWaypointsWithTranslationErrors);
    }
    return flag;
  }

  public void UpdateLocationFromWaypoint(
    int i_index,
    CApAPPWaypoint i_waypoint,
    ITxObject i_location)
  {
    this.UpdateLocationFromWaypoint(i_waypoint, i_location);
    CApAPPWaypoint i_wp = new CApAPPWaypoint(i_waypoint);
    this.Waypoint(i_index, i_wp);
  }

  public override void UpdateLocationFromWaypoint(CApAPPWaypoint i_waypoint, ITxObject i_location)
  {
    KiAppLocationEx locationFromTxLoc = CApAPPObjectFlowTask.CreateAppLocationFromTxLoc(i_location as ITxLocationOperation);
    i_waypoint.StoredApproachLocation = locationFromTxLoc;
  }

  public override CApAPPWaypoint Waypoint(int i_index)
  {
    CApAPPWaypoint i_wp = new CApAPPWaypoint(((KiAppTaskEx) this.KiObjectFlowTask).GetWaypoint(i_index));
    this.configureWaypoint(i_wp, i_index);
    return i_wp;
  }

  public override void Waypoint(int i_index, CApAPPWaypoint i_wp)
  {
    ((KiAppTaskEx) this.KiObjectFlowTask).SetWaypoint(i_index, i_wp.KiWaypoint);
  }

  private KiAppObjectFlowTaskEx KiObjectFlowTask => this.KiTask as KiAppObjectFlowTaskEx;

  internal ITxObject CreateMagnetPointGhost() => this.KiObjectFlowTask.CreateMagnetPointGhost();

  internal void DisableMagnetPoint() => this.KiObjectFlowTask.DisableMagnetPoint();

  public virtual void SetGripLocation(TxTransformation newLocation)
  {
    if (this.ObjectFlowOperation.GripFrameType == 2 || this.ObjectFlowOperation.GripFrameType == 3)
    {
      if (TxTransformation.op_Equality(this.m_initialGripLocation, (TxTransformation) null))
        this.m_initialGripLocation = this.ObjectFlowOperation.GripFrame.AbsoluteLocation;
      this.ObjectFlowOperation.GripFrame.AbsoluteLocation = newLocation;
    }
    else
    {
      if (this.ObjectFlowOperation.GripFrameType != 1)
        return;
      if (TxTransformation.op_Equality(this.m_initialGripLocation, (TxTransformation) null))
        this.m_initialGripLocation = this.ObjectFlowOperation.SimulatedObject.AbsoluteLocation;
      this.ObjectFlowOperation.SimulatedObject.AbsoluteLocation = newLocation;
    }
  }

  public virtual TxTransformation InitialGripLocation
  {
    get
    {
      if (TxTransformation.op_Equality(this.m_initialGripLocation, (TxTransformation) null))
      {
        if (this.ObjectFlowOperation.GripFrameType == 2 || this.ObjectFlowOperation.GripFrameType == 3)
        {
          if (TxTransformation.op_Equality(this.m_initialGripLocation, (TxTransformation) null))
            this.m_initialGripLocation = this.ObjectFlowOperation.GripFrame.AbsoluteLocation;
        }
        else if (this.ObjectFlowOperation.GripFrameType == 1 && TxTransformation.op_Equality(this.m_initialGripLocation, (TxTransformation) null))
          this.m_initialGripLocation = this.ObjectFlowOperation.SimulatedObject.AbsoluteLocation;
      }
      return this.m_initialGripLocation;
    }
    set => this.m_initialGripLocation = value;
  }

  public virtual void ResetGripPosition()
  {
    if (!TxTransformation.op_Inequality(this.m_initialGripLocation, (TxTransformation) null))
      return;
    if (this.ObjectFlowOperation.GripFrameType == 2 || this.ObjectFlowOperation.GripFrameType == 3)
    {
      this.ObjectFlowOperation.GripFrame.AbsoluteLocation = this.InitialGripLocation;
    }
    else
    {
      if (this.ObjectFlowOperation.GripFrameType != 1)
        return;
      this.ObjectFlowOperation.SimulatedObject.AbsoluteLocation = this.InitialGripLocation;
    }
  }

  public KiAppLimitsEx Limits => this.KiObjectFlowTask.GetLimits();

  public enum LimitsCheckMode
  {
    ConsiderDofStatus,
    DontConsiderDofStatus,
  }
}
